package com.zzyl.nursing.service.impl;

import java.util.Collections;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.framework.config.properties.AliIoTConfigProperties;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;

/**
 * 设备Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-10-14
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService
{
    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 查询设备
     * 
     * @param id 设备主键
     * @return 设备
     */
    @Override
    public Device selectDeviceById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询设备列表
     * 
     * @param device 设备
     * @return 设备
     */
    @Override
    public List<Device> selectDeviceList(Device device)
    {
        return deviceMapper.selectDeviceList(device);
    }

    /**
     * 新增设备
     * 
     * @param device 设备
     * @return 结果
     */
    @Override
    public int insertDevice(Device device)
    {
        return save(device) ? 1 : 0;
    }

    /**
     * 修改设备
     * 
     * @param device 设备
     * @return 结果
     */
    @Override
    public int updateDevice(Device device)
    {
        return updateById(device) ? 1 : 0;
    }

    /**
     * 批量删除设备
     * 
     * @param ids 需要删除的设备主键
     * @return 结果
     */
    @Override
    public int deleteDeviceByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除设备信息
     * 
     * @param id 设备主键
     * @return 结果
     */
    @Override
    public int deleteDeviceById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 从物联网平台同步设备列表
     */
    @Override
    public void syncProductList() {
        //请求参数
        QueryProductListRequest request = new QueryProductListRequest();
        request.setPageSize(100);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        //从物联网平台获取设备列表
        QueryProductListResponse response;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException("同步设备列表失败");
        }
        //判断数据是否有值
        if (!response.getBody().getSuccess()){
            throw new BaseException("同步设备列表失败");
        }
        redisTemplate.opsForValue().set(CacheConstants.IOT_PRODUCT_LIST, JSONUtil.toJsonStr(response.getBody().getData().getList().getProductInfo()));
    }

    /**
     * 获取设备列表
     *
     * @return
     */
    @Override
    public List<ProductVo> allProduct() {
        //从缓存中获取设备列表
        String productList = redisTemplate.opsForValue().get(CacheConstants.IOT_PRODUCT_LIST);
        //判断数据是否有值
        if (StringUtils.isEmpty(productList)){
            return Collections.emptyList();
        }
        return JSONUtil.toList(productList, ProductVo.class);
    }

    /**
     * 注册设备
     *
     * @param deviceDto
     */
    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //判断设备是否已有
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeviceName,deviceDto.getDeviceName());
        Long count = count(queryWrapper);
        if (count>0){
            throw new BaseException("设备已存在,请重新输入");
        }
        //保存设备到IOT平台
        //请求参数
        RegisterDeviceRequest request = deviceDto.getRegisterDeviceRequest();
        //设置实例ID
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse response;
        try {
            //调用注册设备接口
            response = client.registerDevice(request);
        } catch (Exception e) {
            throw new BaseException("注册设备失败");
        }
        //判断保存设备到IOT平台是否成功
        if (!response.getBody().success){
            throw new BaseException(response.getBody().getErrorMessage());
        }
        //查询产品信息
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductResponse queryProductResponse;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new BaseException("物联网——查询产品信息失败");
        }
        //判断查询产品信息是否成功
        if (!queryProductResponse.getBody().success){
            throw new BaseException("物联网——查询产品信息失败");
        }
        //设置产品信息到设备对象中
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setProductName(queryProductResponse.getBody().getData().getProductName());

        //判断设备位置
        if (deviceDto.getLocationType().equals(0)){
            device.setPhysicalLocationType(1);
        }
        //补全设备ID
        device.setIotId(response.getBody().getData().getIotId());

        try {
            //保存设备到数据库中
            deviceMapper.insertDevice(device);
        }catch (Exception e){
            //删除IOT平台设备
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setProductKey(device.getProductKey());
            deleteDeviceRequest.setIotId(device.getIotId());
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception exception) {
                throw new BaseException("物联网，删除设备失败");
            }

            throw new BaseException("该位置已绑定设备，请重新绑定");
        }

    }
}
